<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数组reduce</title>
</head>

<body>
    <script>
        /**
         *  reduce()不影响原数组，返回值为新的数据（不一定是数组）
         * 
         * 
            reduce(callbackFn(), [initialValue])
            第一个参数：回调函数
            第二个参数：初始值

            callbackFn(prev, cur, index, arr)
            第一个参数：上一次调用callbackFn的结果
            第二个参数：数组中第N个元素，
            第三个参数：数组中第N个元素的索引，
            第四个参数：数组
        **/
        // 累加器
        let arr = [1, 2, 3, 4];
        let sum = arr.reduce((prev, cur, index, arr) => prev + cur, 10);
        console.log(sum); // 20

        // 统计数组中每一个元素出现的次数
        let pos = ['left', 'right', 'top', 'bottom', 'right']
        let posNum = pos.reduce((prev, cur) => {
            if (cur in prev) {
                prev[cur]++
            } else {
                prev[cur] = 1
            }
            return prev
        }, {})
        console.log(posNum) // { left: 1, right: 2, top: 1, bottom: 1 }

        // 数组去重
        let arr1 = [1, 2, 3, 4, 4, 1]
        let newArr1 = arr1.reduce((pre, cur) => {
            if (!pre.includes(cur)) {
                return pre.concat(cur)
            } else {
                return pre
            }
        }, [])
        console.log(newArr1) // [ 1, 2, 3, 4 ]

        // 数组扁平化
        let arr2 = [1, 2, [3, 4, 5, [6, 7, 8, 9]]]
        let newArr2 = []
        function fn(arr2) {
            arr2.forEach(item => {
                Array.prototype.isPrototypeOf(item) ? fn(item) : newArr2.push(item)
            })
            return newArr2
        }
        console.log(fn(arr2)) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

        // 二维数组扁平化
        let arr3 = [[0, 1], [2, 3], [4, 5]]
        let newArr3 = arr3.reduce((prev, cur) => {
            return prev.concat(cur)
        }, [])
        console.log(newArr3) // [ 0, 1, 2, 3, 4, 5 ]

        // 多维数组扁平化
        let arr4 = [[0, 1], [2, 3], [4, [5, 6, 7, [8, 9]]]]
        function fn(arr4) {
            return arr4.reduce((pre, cur) => {
                return pre.concat(Array.isArray(cur) ? fn(cur) : cur)
            }, [])
        }
        console.log(fn(arr4)) // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]



    </script>
</body>

</html>